﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Net;
using System.IO;

using HtmlAgilityPack;

using System.Web;



namespace SyntaxTaggerMod
{
    public class SyntaxTagger
    {
        Dictionary<string, string> phraseTags = new Dictionary<string, string>();
        Dictionary<string, string> phraseRelations = new Dictionary<string, string>();
        Dictionary<string, string> phraseBaseform = new Dictionary<string, string>();
        List<String> phrasePosition = new List<string>();

        public SyntaxTagger()
        {

        }

        public string readHtml(String inputPhrase)
        {
            HttpWebRequest theHttpRequest;

            string postData = "text=" + inputPhrase + ";system=fdg3es";

            string codeHtml = string.Empty;

            Uri target = new Uri("http://92.243.26.110/cgi-bin/parser.pl");

            theHttpRequest = (HttpWebRequest)HttpWebRequest.Create(target);
            theHttpRequest.Method = "POST";

            //ASCIIEncoding encoding = new ASCIIEncoding();
            //UTF8Encoding encoding = new UTF8Encoding();
            Encoding encoding = Encoding.GetEncoding("ISO-8859-1");

            byte[] byte1 = encoding.GetBytes(postData);

            // Set the content type of the data being posted.
            theHttpRequest.ContentType = "application/x-www-form-urlencoded";

            // Set the content length of the string being posted.
            theHttpRequest.ContentLength = byte1.Length;

            Stream newStream = theHttpRequest.GetRequestStream();

            newStream.Write(byte1, 0, byte1.Length);

            // Close the Stream object.
            newStream.Close();

            StreamReader st = new StreamReader(theHttpRequest.GetResponse().GetResponseStream());

            codeHtml = st.ReadToEnd();

            st.Close();

            int start = codeHtml.IndexOf("<table");
            int end = codeHtml.LastIndexOf("</table>") + 8;

            int size = end - start;

            codeHtml = codeHtml.Substring(start, size);

            start = codeHtml.IndexOf("<tr><tr>") + 4;
            codeHtml = codeHtml.Substring(start);

            start = codeHtml.IndexOf("</table>");
            codeHtml = codeHtml.Remove(start);

            codeHtml = HttpUtility.HtmlDecode(codeHtml);

            codeHtml.Replace("<s>", String.Empty);
            codeHtml.Replace("</s>", String.Empty);

            return codeHtml;
        }

        public void tagPhrase(String inputPhrase)
        {
            String htmlAnswer = this.readHtml(inputPhrase);

            phraseBaseform.Clear();
            phraseRelations.Clear();
            phraseTags.Clear();
            phrasePosition.Clear();

            //Console.Out.WriteLine(htmlAnswer);

            HtmlDocument htmlDoc = new HtmlDocument();

            htmlDoc.LoadHtml(htmlAnswer);

            foreach(HtmlNode row in htmlDoc.DocumentNode.SelectNodes("//tr"))
            {
                string text = row.InnerHtml;

                string theWord = row.SelectSingleNode("td").InnerText;
                theWord = theWord.Trim();

                phrasePosition.Add(theWord);

                try
                {
                    string theRelation = row.SelectSingleNode("td[3]").InnerText;

                    if ( (!phraseRelations.ContainsKey(theRelation)) && (!theRelation.Equals(String.Empty)) )
                    {
                        phraseRelations.Add(theRelation.Trim(), theWord);
                    }
                }
                catch(Exception ex)
                {
                    // Do Nothing
                }

                try
                {
                    string theBaseform = row.SelectSingleNode("td[2]").InnerText;

                    if ((!phraseBaseform.ContainsKey(theBaseform)) && (!theBaseform.Equals(String.Empty)))
                    {
                        phraseBaseform.Add(theWord, theBaseform);
                    }
                }
                catch (Exception ex)
                {
                    // Do Nothing
                }

                string theTag = row.LastChild.InnerText;

                if ((!phraseTags.ContainsKey(theWord)) && (!theWord.Equals(String.Empty)))
                {
                    phraseTags.Add(theWord,theTag);
                }
            }
            /*
            Console.Out.WriteLine("Relaciones:");
            foreach (var relation in phraseRelations.Keys)
            {
                Console.Out.WriteLine("Clave: " + relation );
                Console.Out.WriteLine("Valor: " + phraseRelations[relation]);
            }
            
            Console.Out.WriteLine("Tags:");
            foreach (var tag in phraseTags.Keys)
            {
                Console.Out.WriteLine("Clave: " + tag);
                Console.Out.WriteLine("Valor: " + phraseTags[tag]);
            }

            Console.Out.WriteLine("Baseforms:");
            foreach (var baseform in phraseBaseform.Keys)
            {
                Console.Out.WriteLine("Clave: " + baseform);
                Console.Out.WriteLine("Valor: " + phraseBaseform[baseform]);
            }

            Console.Out.WriteLine("Word Positions:");
            int i = 0;
            foreach (var word in phrasePosition)
            {
                i++;
                Console.Out.WriteLine("["+ i.ToString() +"]" + word);
            }
            */
        }

        public String returnAction()
        {
            try
            {
                return phraseRelations["main>0"];
            }
            catch(Exception ex)
            {
                String[] Tags = phraseTags.Values.ToArray();
                String[] Words = phraseTags.Keys.ToArray();

                for (int i = 0; i < Tags.Length; i++)
                {
                    if (Tags[i].Contains("@MAIN"))
                    {
                        return Words[i];
                    }
                    else
                    {
                        return string.Empty;
                    }
                }
                return string.Empty;
            }   
        }

        public int returnActionPosition(string actionWord)
        {
            int position = phrasePosition.IndexOf(actionWord) + 1;
            return position;
        }

        public String returnSubject(int actionPosition)
        {
            if (phraseRelations.Keys.Contains("v-ch>" + actionPosition.ToString()))
            {
                actionPosition = returnActionPosition( phraseRelations["v-ch>"+actionPosition.ToString()] );
                foreach (var relation in phraseRelations.Keys)
                {
                    if (relation.Contains("subj>" + actionPosition.ToString()))
                    {
                        return phraseRelations[relation];
                    }
                }
            }
            else
            {
                foreach (var relation in phraseRelations.Keys)
                {
                    if (relation.Contains("subj>" + actionPosition.ToString()))
                    {
                        return phraseRelations[relation];
                    }
                }
            }
            
            return String.Empty;
        }

        public String returnObject(int actionPosition)
        {
            foreach (var relation in phraseRelations.Keys)
            {
                if ((relation.Contains("obj>" + actionPosition.ToString())) || (relation.Contains("comp>" + actionPosition.ToString())))
                {
                    return phraseRelations[relation];
                }
            }
            return String.Empty;
        }

        public String returnBaseform(String theWord)
        {
            String baseForm = phraseBaseform[theWord];
            return baseForm;
        }

        public String returnTime(String theWord)
        {
            try
            {
                String wordTag = phraseTags[theWord];

                if (wordTag.Contains("PRES"))
                {
                    return "PRES";
                }
                else if (wordTag.Contains("PRET"))
                {
                    return "PRET";
                }
                else if (wordTag.Contains("FUT"))
                {
                    return "FUT";
                }
                else
                {
                    return "PRES";
                }
            }
            catch (Exception ex)
            {
                return "PRES";
            }
        }

        public String returnGenero(String theWord)
        {
            try
            {
                String wordTag = phraseTags[theWord];

                if (wordTag.Contains("MSC"))
                {
                    return "MSC";
                }
                else if (wordTag.Contains("FEM"))
                {
                    return "FEM";
                }
                else
                {
                    return "MSC";
                }
            }
            catch (Exception ex)
            {
                return "MSC";
            }
        }

        public String returnCardinalidad(String theWord)
        {
            try
            {
                String wordTag = phraseTags[theWord];

                if (wordTag.Contains("PL"))
                {
                    return "PL";
                }
                else if (wordTag.Contains("SG"))
                {
                    return "SG";
                }
                else
                {
                    return "SG";
                }
            }
            catch (Exception ex)
            {
                return "SG";
            }
        }
    }
}
